//引入alova
import { createAlova, Method, type AlovaMethodCreateConfig} from 'alova';
import GlobalFetch from 'alova/GlobalFetch';
import VueHook from 'alova/vue';
import { MylocalStorage } from '../config/storage/MylocalStorage'; // 确保路径正确  
// 案例学习：https://alova.js.org/zh-CN/tutorial/best-practice/manage-apis


//公共请求路径
let url=undefined;
url=import.meta.env.VITE_API_URL;
// url="http://123.60.33.164:9898";


const alova = createAlova({
  //（可选）表示请求的根路径，通过这个 alova 实例发送的请求都会在前面拼接 baseURL，一般设置为域名；
  baseURL: url,
  //设置全局请求超时时间
  // 请求超时时间，单位为毫秒，默认为0，表示永不超时
  timeout: 50000,
  /*
  （必须）它用于确定在 use hook（例如 useRequest）应该如何返回状态化数据，
  目前提供了 VueHook、ReactHook、SvelteHook 分别用于支持 vue、react 和 svelte，statesHook
  将会帮我们创建不同 UI 框架的请求相关的、可以被 Alova 管理的状态，
  包括请求状态 loading、响应数据 data、请求错误对象 error 等；
  */
  statesHook: VueHook,
  /**
   全局关闭缓存模式
   如果在你的项目中不希望使用任何请求缓存，可以在全局将它关闭，如果希望只在特定的几个请求中使用，
   也可以全局关闭它，并在指定的Method实例中设置即可。
  */
  // 设置为null即可全局关闭全部请求缓存
  localCache: null,
  /*
  （必须）请求适配器，请求适配器将用于所有请求的发送，
  请求发送模块和具体的请求信息是解耦的。在示例代码中使用了默认提供的 GlobalFetch，
  它由window.fetch提供请求支持。
  */
  requestAdapter: GlobalFetch(),
  shareRequest: true,
  /*
  设置全局请求拦截器：
  通常，我们需要让所有请求都用上相同的配置，例如添加 token、timestamp 到请求头，
  alova为我们提供了全局的请求拦截器，它将在请求前被触发，
  我们可以在此拦截器中统一设置请求参数，这也与axios相似。
  */
  beforeRequest(method) {
    // 假设我们需要添加token到请求头
    // console.log(method);
    let isHeaders=false;
    MylocalStorage.getItem("token").then(res=>{
      if(res!=null){
        isHeaders=true;
      }
    })
    if(isHeaders){
      method.config.headers.token = MylocalStorage.getItem("token");
    }
  },
  /*
  设置全局响应拦截器:
  当我们希望统一解析响应数据、统一处理错误时，
  此时可以在创建alova实例时指定全局的响应拦截器，这同样与axios相似。
  响应拦截器包括请求成功的拦截器和请求失败的拦截器。
  */
  responded: {
    // 请求成功的拦截器
    // 当使用GlobalFetch请求适配器时，第一个参数接收Response对象
    // 第二个参数为当前请求的method实例，你可以用它同步请求前后的配置信息
      // @ts-ignore
    onSuccess: async (response:any, method:string) => {
      // console.log("请求成功了");
        if (response.code >= 400) {
          throw new Error(response.statusText);
        }
        const json = await response.json();
        if (json.code !== 200) {
          // 抛出错误或返回reject状态的Promise实例时，此请求将抛出错误
          
          // throw new Error(json.message);
        }

        // 解析的响应数据将传给method实例的transformData钩子函数，这些函数将在后续讲解
        return json;
    },

    // 请求失败的拦截器
    // 请求错误时将会进入该拦截器。
    // 第二个参数为当前请求的method实例，你可以用它同步请求前后的配置信息
      // @ts-ignore
    onError: (err, method) => {
      console.log("请求错误了");
      alert(err.message);
    }
  }


});
/**
 * 封装Alova
 * 统一传参
 */
/**
 * 封装Alova
 * 统一传参
 */
interface Data {
  [index: string]: unknown
}
type Config = AlovaMethodCreateConfig<unknown, unknown, RequestInit, Headers> | undefined

interface Http {
  get: (
    url: string,
    data?: Data,
    config?: Config
  ) => Method
  post: (
    url: string,
    data?: Data | Array<string> | FormData  | string[],
    config?: Config,
  ) => Method
  put: (
    url: string,
    data?: Data,
    config?: Config,
  ) => Method
  patch: (
    url: string,
    data?: Data,
    config?: Config,
  ) => Method
  delete: (
    url: string,
    data?: Data,
    config?: Config,
  ) => Method
}

const http: Http = {
  get(url: string, data?: any, config = {}) {
    return alova.Get(url, {
      params: data,
      ...config,
    })
  },
  post(url: any, data: any, config = {}) {
    return alova.Post(url, data, config)
  },
  put(url: any, data: any, config = {}) {
    return alova.Put(url, data, config)
  },
  patch(url: any, data: any, config = {}) {
    return alova.Patch(url, data, config)
  },
  delete(url: any, data: any, config = {}) {
    return alova.Delete(url, {
      data,
      ...config,
    })
  },
}

export default http;



